﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace Algorithms.Expressions
{
    public class LambdaExpressionTreeEvaluator : IExpressionTreeEvaluator
    {
        [ThreadStatic]
        private static Expression _lastExpressionTree;
        [ThreadStatic]
        private static Func<double, double> _lastCompiledFunc;

        public double Evaluate(Expression tree, double input)
        {
            // cache the func for performance sake
            if (_lastExpressionTree != tree)
            {
                var lambdaExpression = Expression.Lambda<Func<double, double>>(tree, new[]
                {
                    ExpressionFactoryContainer.DefaultInputParameterExpression
                });

                _lastExpressionTree = tree;
                _lastCompiledFunc = lambdaExpression.Compile();
            }

            return _lastCompiledFunc(input);
        }
    }
}
